package org.flexharmony.eclipse.properties.classinclusion;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.flexharmony.eclipse.HarmonyPlugin;
import org.flexharmony.eclipse.domain.ExclusionFilter;
import org.flexharmony.eclipse.domain.Filter;
import org.flexharmony.eclipse.domain.IncludedSourceFolder;
import org.flexharmony.eclipse.domain.InclusionFilter;
import org.flexharmony.eclipse.properties.AbstractHarmonyPropertiesPanel;

public class IncludedSourceFolderPanel extends AbstractHarmonyPropertiesPanel implements ISelectionChangedListener
{
  private IProject project;
  private TreeViewer treeViewier;
  private IncludedSourceFolderContentProvider contentProvider;
  
  private Button addFolderBtn;
  private Button editBtn;
  private Button removeBtn;
  
  private boolean valuesChanged;
  
  public IncludedSourceFolderPanel(IProject project, Composite parent)
  {
    super(project, parent);
    
    this.project = project;
    
    createLayout();
  }
  
  public void save() throws CoreException
  {
    IncludedSourceFolderMarshaller.save(contentProvider.getSourceFolders(), project);
  }

  /**
   * @see ISelectionChangedListener#selectionChanged(SelectionChangedEvent)
   */
  public void selectionChanged(SelectionChangedEvent event)
  {
    TreeSelection selection = (TreeSelection)treeViewier.getSelection();
    Object element = selection.getFirstElement();
    if (element instanceof IncludedSourceFolder)
    {
      removeBtn.setEnabled(true);
      editBtn.setEnabled(false);
    }
    else if (element instanceof Filter)
    {
      Filter filter = (Filter)element;
      removeBtn.setEnabled(filter.patterns.size() > 0);
      editBtn.setEnabled(true);
    }
    else
    {
      removeBtn.setEnabled(false);
      editBtn.setEnabled(false);
    }
  }
  
  public boolean valuesChanged()
  {
    return valuesChanged;
  }
  
  private void createLayout()
  {
    GridLayout panelLayout = new GridLayout();
    panelLayout.marginHeight = 0;
    panelLayout.marginWidth = 0;
    panelLayout.numColumns = 2;
    panelLayout.verticalSpacing = 0;
    setLayout(panelLayout);  

    contentProvider = new IncludedSourceFolderContentProvider(project);
    treeViewier = new TreeViewer(this, SWT.SINGLE | SWT.BORDER);
    treeViewier.setContentProvider(contentProvider);
    treeViewier.setLabelProvider(contentProvider);
    treeViewier.setInput(project);
    treeViewier.addSelectionChangedListener(this);
    GridData treeGridData = new GridData();
    treeGridData.grabExcessVerticalSpace = true;
    treeGridData.grabExcessHorizontalSpace = true;
    treeGridData.verticalAlignment = GridData.FILL;
    treeGridData.horizontalAlignment = GridData.FILL;
    treeGridData.verticalIndent = 7;
    treeViewier.getTree().setLayoutData(treeGridData);

    GridLayout buttonPanelLayout = new GridLayout();
    buttonPanelLayout.numColumns = 1;
    Canvas buttonPanel = new Canvas(this, SWT.NONE);
    buttonPanel.setLayout(buttonPanelLayout);
    GridData buttonPanelData = new GridData();
    buttonPanelData.verticalAlignment = org.eclipse.swt.layout.GridData.BEGINNING;
    buttonPanel.setLayoutData(buttonPanelData);

    GridData buttonData = new GridData();
    buttonData.verticalAlignment = org.eclipse.swt.layout.GridData.BEGINNING;
    buttonData.widthHint = 125;
    addFolderBtn = new Button(buttonPanel, SWT.NONE);
    addFolderBtn.setText("Add Folder...");
    addFolderBtn.setLayoutData(buttonData);
    addFolderBtn.addSelectionListener(new SelectionAdapter()
    {
      public void widgetSelected(SelectionEvent sevt)
      {
        addFolder();
      }
    });

    editBtn = new Button(buttonPanel, SWT.NONE);
    editBtn.setText("Edit...");
    editBtn.setLayoutData(buttonData);
    editBtn.setEnabled(false);
    editBtn.addSelectionListener(new SelectionAdapter()
    {
      public void widgetSelected(SelectionEvent sevt)
      {
        edit();
      }
    });


    removeBtn = new Button(buttonPanel, SWT.NONE);
    removeBtn.setText("Remove");
    removeBtn.setLayoutData(buttonData);
    removeBtn.setEnabled(false);
    removeBtn.addSelectionListener(new SelectionAdapter()
    {
      public void widgetSelected(SelectionEvent sevt)
      {
        remove();
      }
    });
 }
  
  private void addFolder()
  {
    AddSourceFoldersDialog dialog = new AddSourceFoldersDialog(getShell(), project, contentProvider.getSourceFolders());
    dialog.open();
    
    if (dialog.isAdd())
    {
      List<IPath> folderPaths = dialog.getSelectedFolders();
      List<IncludedSourceFolder> addedFolders = new ArrayList<IncludedSourceFolder>();
      for (IPath folderPath : folderPaths)
      {
        IncludedSourceFolder folder = new IncludedSourceFolder(folderPath);
        folder.setIncludedFilter(new InclusionFilter(folder));
        folder.setExcludedFilter(new ExclusionFilter(null, folder));
        
        contentProvider.getSourceFolders().add(folder);
        addedFolders.add(folder);
        valuesChanged = true;
      }
      
      treeViewier.refresh();
      for (IncludedSourceFolder addedFolder : addedFolders)
      {
        treeViewier.expandToLevel(addedFolder, -1);
      }
    }
  }
  
  private void edit()
  {
    Object element = ((ITreeSelection)treeViewier.getSelection()).getFirstElement();
    if (element instanceof Filter)
    {
      IncludedSourceFolder folder = ((Filter)element).parent;
      Shell parent = HarmonyPlugin.getInstance().getWorkbench().getDisplay().getActiveShell();

      InclusionExclusionDialog inclusionExclusionDialog = new InclusionExclusionDialog(folder, project);
      WizardDialog wizardDialog = new WizardDialog(parent, inclusionExclusionDialog);
      wizardDialog.create();
      wizardDialog.open();
      treeViewier.refresh();
      selectionChanged(null);
      valuesChanged = true;
    }
    
  }
  
  private void remove()
  {
    Object element =((TreeSelection)treeViewier.getSelection()).getFirstElement();
    if (element instanceof IncludedSourceFolder)
    {
      contentProvider.getSourceFolders().remove((IncludedSourceFolder)element);
      treeViewier.refresh();
    }
    else if (element instanceof Filter)
    {
      ((Filter)element).patterns.clear();
      treeViewier.refresh();
    }
    valuesChanged = true;
    selectionChanged(null);
  }
}
